package com.erpanderp.wam.usm.view.leave;

import java.io.IOException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.swing.SwingWorker;

import org.hibernate.validator.xml.ValidatedByType;
import org.primefaces.context.RequestContext;

import com.erpanderp.wam.usm.model.entity.leave.EmployeeLeave;
import com.erpanderp.wam.usm.model.entity.leave.LeaveBalance;
import com.erpanderp.wam.usm.model.entity.timesheet.TimesheetDetail;
import com.erpanderp.wam.usm.model.entity.user.Employee;
import com.erpanderp.wam.usm.model.entity.user.EmployeeAndReporting;
import com.erpanderp.wam.usm.model.entity.user.WAMUser;
import com.erpanderp.wam.usm.model.service.leave.EmployeeLeaveDAO;
import com.erpanderp.wam.usm.model.service.leave.LeaveBalanceDAO;
import com.erpanderp.wam.usm.model.service.timesheet.TimesheetDetailDAO;
import com.erpanderp.wam.usm.model.service.user.EmployeeAndReportingDAO;
import com.erpanderp.wam.usm.model.service.user.EmployeeDAO;
import com.erpanderp.wam.util.CommonLookup;
import com.erpanderp.wam.util.EmailUtil;
import com.erpanderp.wam.util.ValidationUtil;
import com.erpanderp.wam.util.WAMHostManager;

@ManagedBean
@ViewScoped
public class ApproveLeaveBean implements Serializable {
	HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
			.getExternalContext().getSession(true);
	ServletContext context = (ServletContext) FacesContext.getCurrentInstance()
			.getExternalContext().getContext();
	private static final long serialVersionUID = 1L;
	private String leaveCODE = null;
	private EmployeeLeave employeeLeave = new EmployeeLeave();
	private EmployeeLeaveDAO employeeLeaveDAO;
	private boolean FORM_VALID;
	private WAMUser wamUser = new WAMUser();
	private EmailUtil emailUtil;
	private String leaveApprovedAlready;
	private boolean leaveApprovedFlag = true;
	private LeaveBalance leaveBalance = new LeaveBalance();
	private Float actualLeaveBalance;
	private Float currentLeaveBalance;
	private Float diductedLeaves;
	private Float remainingLeaves;
	private LeaveBalanceDAO leaveBalanceDAO = new LeaveBalanceDAO();
	private HtmlOutputText leaveApprovedAlreadyHtmlOutputText = new HtmlOutputText();
	private SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy");
	HttpServletRequest request = (HttpServletRequest) FacesContext
			.getCurrentInstance().getExternalContext().getRequest();
	private EmployeeAndReporting employeeAndReporting;
	private EmployeeAndReportingDAO employeeAndReportingDAO = new EmployeeAndReportingDAO();
	private String employeeCode;
	private Employee employee;
	private EmployeeDAO employeeDAO = new EmployeeDAO();
	private String leaveFromToBeDisplayed;
	private String leaveToToBeDisplayed;

	public ApproveLeaveBean() {
		wamUser = (WAMUser) session
				.getAttribute(CommonLookup.SESSION_ATTRIBUTE_WAMUSER);

		System.out.println("IN APPROVE LEAVE ACTION");
		leaveCODE = request.getParameter("leaveCODE");
		employeeCode = request.getParameter("EMPID");
		
		  employee = employeeDAO.getEmployeeByEmployeeCode(employeeCode);
		  employeeAndReporting =
		  employeeAndReportingDAO.getEmployeeReportingDetail(employee.getEmployeeId());
		
		if (request.getParameter("leaveCODE") != null) {
			employeeLeaveDAO = new EmployeeLeaveDAO();
			employeeLeave = employeeLeaveDAO
					.getEmployeeLeaveByLeaveCODE(leaveCODE);
			leaveFromToBeDisplayed = formatter.format(employeeLeave
					.getPeriodFrom());
			leaveToToBeDisplayed = formatter
					.format(employeeLeave.getPeriodTo());
			if (employeeLeave.getApprovalStatus().equals(
					CommonLookup.LEAVE_APPROVED_STATUS)
					|| employeeLeave.getApprovalStatus().equals(
							CommonLookup.LEAVE_REJECT_STATUS)) {
				System.out.println("LEAVE APPROVED/REJECTED BEFORE");

				leaveApprovedFlag = false;
			} else {
				leaveApprovedFlag = true;

			}
		} else {
			ValidationUtil.gotoLoginPage();
		}

		System.out.println("IN APPROVE LEAVE BEAN");
	}

	public String approveRejectLeaveAction(ActionEvent actionEvent) {
		UIComponent uiData = actionEvent.getComponent();
		String messageString = null;

		String leaveFROM = formatter.format(employeeLeave.getPeriodFrom());
		String leaveTO = formatter.format(employeeLeave.getPeriodTo());
		System.out.println("ACTION COMMAND  IS :"
				+ actionEvent.getComponent().getId());
		System.out.println("IN APPROVE LEAVE ACTION");
		validate();
		if (FORM_VALID) {

			

				Map<String, String> hostsMap = WAMHostManager.getWAMHosts(context);
				emailUtil = new EmailUtil();
				if (hostsMap.get(CommonLookup.DEV_EMAIL) == null) {
					System.out.println("PRODUCTION");
					String[] to = { employeeLeave.getEmployee().getEmail() };
					emailUtil.setRecieverAddresses(to);
				} else {
					System.out.println("DEVELOPMENT");
					String[] to = { hostsMap.get(CommonLookup.DEV_EMAIL) };
					emailUtil.setRecieverAddresses(to);
				}

				if (actionEvent.getComponent().getId().equals("Approve")) {
					employeeLeave
							.setApprovalStatus(CommonLookup.LEAVE_APPROVED_STATUS);
					employeeLeave.setManagerActionAcknowledged(CommonLookup.LEAVE_REQUEST_MANAGER_ACTION_NOT_ACKNOWLEDGED);

					employeeLeaveDAO
							.leaveApprovedByApprovalComments(employeeLeave);
					
					//Update timesheet if exist
					System.out.println("Timesheet Updated: " + updateTimesheetIfExist());
					
					messageString = "Dear "
							+ employeeLeave.getEmployee().getFirstName()
							+ " "
							+ employeeLeave.getEmployee().getLastName()
							+ ",<br /><br />"
							+

							"<table border='0'>"
							+ "<tr> <td>Leave Description </td><td> : </td><td>"
							+ employeeLeave.getReason() + " </td></tr>"
							+ "<tr> <td>Leave Type</td><td> : </td> <td>"
							+ employeeLeave.getLeaveType().getLeaveType()
							+ "</td></tr>" +

							"</table><br/><br/>" +

							"Your leave request is approved from " + leaveFROM
							+ " to " + leaveTO + " with approver comments : "
							+ employeeLeave.getApprovalComments()
							+ "<br /><br />" +

							"Thanks & Regards, <br />"+CommonLookup.WAM_DEVTEAM_SIGNATURE;
				} else {
					System.out.println("COMPONENT ID IS :"
							+ actionEvent.getComponent().getId());
					employeeLeave
							.setApprovalStatus(CommonLookup.LEAVE_REJECT_STATUS);
					employeeLeave.setApprovalComments(employeeLeave
							.getApprovalComments());
					
					employeeLeave.setManagerActionAcknowledged(CommonLookup.LEAVE_REQUEST_MANAGER_ACTION_NOT_ACKNOWLEDGED);
					
					employeeLeaveDAO
							.leaveRejectedByApprovalComments(employeeLeave);

					FacesContext.getCurrentInstance().addMessage(
							null,
							new FacesMessage(FacesMessage.SEVERITY_INFO,
									" Leave Request Rejected.", ""));
					messageString = "Dear "
							+ employeeLeave.getEmployee().getFirstName()
							+ " "
							+ employeeLeave.getEmployee().getLastName()
							+ ",<br /><br />"
							+

							"<table border='0'>"
							+ "<tr> <td>Leave Description </td><td> : </td><td>"
							+ employeeLeave.getReason() + " </td></tr>"
							+ "<tr> <td>Leave Type</td><td> : </td> <td>"
							+ employeeLeave.getLeaveType().getLeaveType()
							+ "</td></tr>" +

							"</table><br/><br/>" +

							"Your leave request is rejected from " + leaveFROM
							+ " to " + leaveTO + "with approver comments : "
							+ employeeLeave.getApprovalComments()
							+ "<br /><br />" +

							"Thanks & Regards, <br />WAM - Dev TEAM";
				}
				// emailUtil.setRecieverAddresses();
				emailUtil.setMessage(messageString);
				emailUtil.setSenderEmail("podquick@erpanderp.com",
						"WAM - Dev Team");

				if (actionEvent.getComponent().getId().equals("Approve")) {
					leaveBalance = new LeaveBalance();
					leaveBalance = leaveBalanceDAO
							.getActualLeaveBalanceByLeaveTypeIdAndEmployeeId(
									employeeLeave.getLeaveType()
											.getLeaveTypeid(), employeeLeave
											.getEmployee().getEmployeeId());
					System.out.println(employeeLeave.getLeaveType()
							.getLeaveType()
							+ " - ACTUAL BALANCE IS "
							+ leaveBalance.getBalance());
					System.out.println(employeeLeave.getLeaveType()
							.getLeaveType()
							+ " - APPLIED LEAVES ARE "
							+ employeeLeave.getNoOfDays());
					if (employeeLeave.getLeaveType().getLeaveType()
							.equals(CommonLookup.WORKFROMHOME_TYPE)) {
						System.out
								.println("APPROVED LEAVE TYPE IN IF IS-----------------> ="
										+ employeeLeave.getLeaveType()
												.getLeaveType());
						remainingLeaves = leaveBalance.getBalance()
								+ employeeLeave.getNoOfDays();
					} else if (employeeLeave.getLeaveType().getLeaveType()
							.equals(CommonLookup.LOSS_OF_PAY_TYPE)) {

						System.out
								.println("APPROVED LEAVE TYPE IN LOP IF IS----------------> ="
										+ employeeLeave.getLeaveType()
												.getLeaveType());
						remainingLeaves = leaveBalance.getBalance()
								+ employeeLeave.getNoOfDays();

					}else if (employeeLeave.getLeaveType().getLeaveType()
								.equals(CommonLookup.COMP_OF_TYPE)) {

							System.out
									.println("APPROVED LEAVE TYPE IN COMP OFF IF IS----------------> ="
											+ employeeLeave.getLeaveType()
													.getLeaveType());
							remainingLeaves = leaveBalance.getBalance()
									+ employeeLeave.getNoOfDays();

						}else {
						System.out.println("APPROVED LEAVE TYPE IN ELSE IS ="
								+ employeeLeave.getLeaveType().getLeaveType());
						remainingLeaves = leaveBalance.getBalance()
								- employeeLeave.getNoOfDays();
					}
					System.out.println(employeeLeave.getLeaveType()
							.getLeaveType()
							+ " - REMAINING LEAVES ARE "
							+ remainingLeaves);
					leaveBalance.setBalance(remainingLeaves);
					leaveBalance.getLeaveType().setLeaveTypeid(
							employeeLeave.getLeaveType().getLeaveTypeid());
					leaveBalanceDAO.updateLeaveBalance(leaveBalance);
					emailUtil.setSubject(employeeLeave.getEmployee()
							.getFirstName()
							+ " ("
							+ leaveCODE
							+ ") "
							+ "Leave Request is Approved");
					FacesContext
							.getCurrentInstance()
							.addMessage(
									null,
									new FacesMessage(
											FacesMessage.SEVERITY_INFO,
											" Leave Request Approved successfully.",
											""));
				} else {
					emailUtil.setSubject(employeeLeave.getEmployee()
							.getFirstName()
							+ " ("
							+ leaveCODE
							+ ") "
							+ "Leave Request is Rejected");
				}

				SwingWorker worker = new SwingWorker<String, Object>() {

					@Override
					protected String doInBackground() throws Exception {
						// TODO Auto-generated method stub

						emailUtil.processAndSendEmail();
						return null;
					}

					@Override
					protected void done() {
						// TODO Auto-generated method stub
						System.out.println("MAIL SENT");
						// super.done();
					}
				};
				worker.execute();

				employeeLeave = new EmployeeLeave();
			}
		 else {

		}
		return "approveleave";

	}

	
	private boolean updateTimesheetIfExist(){
		boolean UPDATED = false;
		System.out.println("trying to update timesheet...");
		try{
			TimesheetDetailDAO timesheetDetailDAO = new TimesheetDetailDAO();
			List<TimesheetDetail> timesheetDetails = (List<TimesheetDetail>) timesheetDetailDAO.getTimesheetDetails(employeeLeave.getPeriodFrom(), employeeLeave.getPeriodTo(), employeeLeave.getEmployee().getEmployeeId());
			System.out.println(timesheetDetails != null ? timesheetDetails.size() : "ZEROOOOOOOOOOOO");
			Date now = new Date();
			for(TimesheetDetail timesheetDetail : timesheetDetails){
				timesheetDetail.setDateModified(now);
				timesheetDetail.setModifiedBy(employeeLeave.getApprover().getFirstName());
				if(employeeLeave != null && employeeLeave.getNoOfDays() == 0.5){
					timesheetDetail.setTimesheetDetailStatus(CommonLookup.HALFDAY_STATUS);	
				}else{
				  timesheetDetail.setTimesheetDetailStatus(employeeLeave.getLeaveType().getLeaveType());
				}
				
				timesheetDetailDAO.updateTimesheetDetail(timesheetDetail);
				
			}
			return UPDATED;
		}catch (Exception e) {
			e.printStackTrace();
			return false;
		}				
	}
	
	
	public boolean validate() {
		System.out.println("IN VALIDATE METHOD");
		FORM_VALID = true;
		if (ValidationUtil.isEmpty(employeeLeave.getApprovalComments(),
				"Approvar Comments", null, FacesContext.getCurrentInstance()) != null) {
			System.out.println("LEAVE APPROVAL STATUS IS EMPTY");

			FORM_VALID = false;

		}

		return FORM_VALID;
	}

	public String getLeaveCODE() {
		return leaveCODE;
	}

	public void setLeaveCODE(String leaveCODE) {
		this.leaveCODE = leaveCODE;
	}

	public EmployeeLeave getEmployeeLeave() {
		return employeeLeave;
	}

	public void setEmployeeLeave(EmployeeLeave employeeLeave) {
		this.employeeLeave = employeeLeave;
	}

	public EmployeeLeaveDAO getEmployeeLeaveDAO() {
		return employeeLeaveDAO;
	}

	public void setEmployeeLeaveDAO(EmployeeLeaveDAO employeeLeaveDAO) {
		this.employeeLeaveDAO = employeeLeaveDAO;
	}

	public boolean isFORM_VALID() {
		return FORM_VALID;
	}

	public void setFORM_VALID(boolean fORM_VALID) {
		FORM_VALID = fORM_VALID;
	}

	public EmailUtil getEmailUtil() {
		return emailUtil;
	}

	public void setEmailUtil(EmailUtil emailUtil) {
		this.emailUtil = emailUtil;
	}

	public String getLeaveApprovedAlready() {
		return leaveApprovedAlready;
	}

	public void setLeaveApprovedAlready(String leaveApprovedAlready) {
		this.leaveApprovedAlready = leaveApprovedAlready;
	}

	public boolean isLeaveApprovedFlag() {
		return leaveApprovedFlag;
	}

	public void setLeaveApprovedFlag(boolean leaveApprovedFlag) {
		this.leaveApprovedFlag = leaveApprovedFlag;
	}

	public HtmlOutputText getLeaveApprovedAlreadyHtmlOutputText() {
		return leaveApprovedAlreadyHtmlOutputText;
	}

	public void setLeaveApprovedAlreadyHtmlOutputText(
			HtmlOutputText leaveApprovedAlreadyHtmlOutputText) {
		this.leaveApprovedAlreadyHtmlOutputText = leaveApprovedAlreadyHtmlOutputText;
	}

	public LeaveBalance getLeaveBalance() {
		return leaveBalance;
	}

	public void setLeaveBalance(LeaveBalance leaveBalance) {
		this.leaveBalance = leaveBalance;
	}

	public Float getActualLeaveBalance() {
		return actualLeaveBalance;
	}

	public void setActualLeaveBalance(Float actualLeaveBalance) {
		this.actualLeaveBalance = actualLeaveBalance;
	}

	public Float getCurrentLeaveBalance() {
		return currentLeaveBalance;
	}

	public void setCurrentLeaveBalance(Float currentLeaveBalance) {
		this.currentLeaveBalance = currentLeaveBalance;
	}

	public Float getDiductedLeaves() {
		return diductedLeaves;
	}

	public void setDiductedLeaves(Float diductedLeaves) {
		this.diductedLeaves = diductedLeaves;
	}

	public WAMUser getWamUser() {
		return wamUser;
	}

	public void setWamUser(WAMUser wamUser) {
		this.wamUser = wamUser;
	}

	public Float getRemainingLeaves() {
		return remainingLeaves;
	}

	public void setRemainingLeaves(Float remainingLeaves) {
		this.remainingLeaves = remainingLeaves;
	}

	public EmployeeAndReporting getEmployeeAndReporting() {
		return employeeAndReporting;
	}

	public void setEmployeeAndReporting(
			EmployeeAndReporting employeeAndReporting) {
		this.employeeAndReporting = employeeAndReporting;
	}

	public String getEmployeeCode() {
		return employeeCode;
	}

	public void setEmployeeCode(String employeeCode) {
		this.employeeCode = employeeCode;
	}

	public Employee getEmployee() {
		return employee;
	}

	public void setEmployee(Employee employee) {
		this.employee = employee;
	}

	public String getLeaveFromToBeDisplayed() {
		return leaveFromToBeDisplayed;
	}

	public void setLeaveFromToBeDisplayed(String leaveFromToBeDisplayed) {
		this.leaveFromToBeDisplayed = leaveFromToBeDisplayed;
	}

	public String getLeaveToToBeDisplayed() {
		return leaveToToBeDisplayed;
	}

	public void setLeaveToToBeDisplayed(String leaveToToBeDisplayed) {
		this.leaveToToBeDisplayed = leaveToToBeDisplayed;
	}

}
